package com.atomgit.ai.proxy.service.impl;

import com.atomgit.ai.proxy.entity.ModelInfo;
import com.atomgit.ai.proxy.entity.UserApiKey;
import com.atomgit.ai.proxy.mapper.ModelInfoMapper;
import com.atomgit.ai.proxy.mapper.UserApiKeyMapper;
import com.atomgit.ai.proxy.param.PromptParam;
import com.atomgit.ai.proxy.processor.service.ParamAndResponseProcessor;
import com.atomgit.ai.proxy.service.ModelInfoService;
import com.atomgit.ai.proxy.util.HTTPUtil;
import com.atomgit.ai.proxy.vo.ModelAnswerVO;
import com.atomgit.ai.proxy.vo.ModelInfoSelfVO;
import com.atomgit.ai.proxy.vo.ModelInfoVO;
import com.atomgit.ai.proxy.vo.ModelVersionVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class ModelInfoServiceImpl implements ModelInfoService {

    @Autowired
    private ModelInfoMapper modelInfoMapper;

    @Autowired
    private UserApiKeyMapper userApiKeyMapper;

    @Autowired
    private HTTPUtil httpProxyStreamUtil;

    @Override
    public List<ModelInfoVO> list() {
        List<ModelInfoVO> modelInfoVOS = new ArrayList<>();
        List<ModelInfo> modelInfos = modelInfoMapper.selectAll();
        for (ModelInfo modelInfo : modelInfos){
             ModelInfoVO modelInfoVO = new ModelInfoVO();
             BeanUtils.copyProperties(modelInfo,modelInfoVO);
             List<String> versionList = Arrays.asList(modelInfo.getVersion().split(","));
             List<ModelVersionVO> modelVersionVOList = new ArrayList<>();
             for (int i = 0; i < versionList.size(); i++) {
                String version =  versionList.get(i);
                ModelVersionVO modelVersionVO = new ModelVersionVO();
                modelVersionVO.setVersion(version);
                modelVersionVOList.add(modelVersionVO);
             }
             modelInfoVO.setVersionList(modelVersionVOList);
             modelInfoVOS.add(modelInfoVO);
        }
        return modelInfoVOS;
    }

    @Override
    public ModelAnswerVO answer(PromptParam param) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        log.info("获取指定模型回答...");
        ModelInfo modelInfo = modelInfoMapper.selectById(param.getModelId());
        // 根据userId及modelId查询指定apiKey
        UserApiKey userApiKey = userApiKeyMapper.selectByModelIdAndVersion(param.getModelId(),param.getVersion());
        String apiKey = userApiKey.getApiKey();
        // 初始化模型处理类并处理参数与返回结果
        Class<?> aClass = Class.forName(modelInfo.getProcessorClassPath());
        ParamAndResponseProcessor paramAndResponseProcessor = (ParamAndResponseProcessor) aClass.newInstance();
        String requestBody = paramAndResponseProcessor.generateRequestBody(param);
        String responseBody = httpProxyStreamUtil.sendRequest(modelInfo.getRequestUrl(), HttpMethod.POST, requestBody, apiKey);
        return paramAndResponseProcessor.generateModelAnswerVO(responseBody);
    }

    @Override
    public void answerInStream(PromptParam param, HttpServletResponse response) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        log.info("获取指定模型回答并以流式返回结果...");
        ModelInfo modelInfo = modelInfoMapper.selectById(param.getModelId());
        // 根据userId及modelId查询指定apiKey
        UserApiKey userApiKey = userApiKeyMapper.selectByModelIdAndVersion(param.getModelId(),param.getVersion());
        String apiKey = userApiKey.getApiKey();
        // 初始化模型处理类并处理参数与返回结果
        Class<?> aClass = Class.forName(modelInfo.getProcessorClassPath());
        ParamAndResponseProcessor paramAndResponseProcessor = (ParamAndResponseProcessor) aClass.newInstance();
        String requestBody = paramAndResponseProcessor.generateRequestBody(param);
        httpProxyStreamUtil.sendRequestInStream(modelInfo.getRequestUrl(), HttpMethod.POST,requestBody,apiKey,response,paramAndResponseProcessor);
    }

    @Override
    public List<ModelInfoSelfVO> listSelf() {
        List<ModelInfoSelfVO> modelInfoSelfVOS = new ArrayList<>();
        List<UserApiKey> userApiKeys = userApiKeyMapper.selectAll();
        for (UserApiKey userApiKey : userApiKeys){
            ModelInfoSelfVO modelInfoSelfVO = new ModelInfoSelfVO();
            BeanUtils.copyProperties(userApiKey,modelInfoSelfVO);
            modelInfoSelfVO.setApiKey(userApiKey.getApiKey());
            modelInfoSelfVO.setName(userApiKey.getCustomModelName());
            modelInfoSelfVO.setModelId(userApiKey.getModelId());
            modelInfoSelfVOS.add(modelInfoSelfVO);
        }
        return modelInfoSelfVOS;
    }

}